

package com.hdu.async_initialize_bean.registrar;


import com.google.common.collect.Lists;
import com.hdu.async_initialize_bean.threadFactory.NamedThreadFactory;
import com.hdu.async_initialize_bean.helper.SpringBeanHelper;
import com.hdu.async_initialize_bean.holder.ApplicationContextHolder;
import com.hdu.async_initialize_bean.processor.AsyncInitBeanPostProcessor;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class AsyncInitBaseBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    private static final String APPLICATION_CONTEXT_HOLDER = "asyncInitApplicationContextHolder";
    private static final String ASYNC_INIT_BEAN_POST_PROCESSOR = "asyncInitBeanPostProcessor";
    private static final String DEFAULT_THREAD_POOL_NAME = "asyncInitExecutor";

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        SpringBeanHelper.registerIfAbsent(registry, APPLICATION_CONTEXT_HOLDER, ApplicationContextHolder.class);
        SpringBeanHelper.registerIfAbsent(
                registry,
                DEFAULT_THREAD_POOL_NAME,
                ThreadPoolExecutor.class,
                null,
                buildConstructorArgs()
        );
        SpringBeanHelper.registerIfAbsent(
                registry,
                ASYNC_INIT_BEAN_POST_PROCESSOR,
                AsyncInitBeanPostProcessor.class,
                null,
                Lists.newArrayList(APPLICATION_CONTEXT_HOLDER, DEFAULT_THREAD_POOL_NAME)
        );
    }

    private Object[] buildConstructorArgs() {
        return new Object[]{
                6, // 核心线程池大小
                8, // 最大线程池大小
                60, // 线程空闲时间
                TimeUnit.SECONDS, // 线程空闲时间的单位
                new ArrayBlockingQueue<>(2000), // 任务队列
                new NamedThreadFactory("asyncInit"), // 线程工厂，用于创建具有指定名称前缀的线程
                new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝处理策略
        };
    }
}
